<script setup lang="ts">
// 泛型出现的动机 解决类型丢失问题
// 提高代码的复用与灵活度
// arg: T表示函数的参数arg的类型是由这个类型参数T来决定的，也就是调用者传入什么类型的数据作为参数，T就代表那个类型。
// : T在函数返回值的位置，表示函数的返回值类型也是T，意味着函数返回的数据类型和传入的参数类型是一致的。
function echo<T>(arg: T): T {
  return arg
}

const result = echo<string>('hello')
console.log(result)
const resultNum = echo<number>(123)
console.log(resultNum)

// 泛型是可以写多个的
function swap<T, U>(tuple: [T, U]): [U, T] {
  return [tuple[1], tuple[0]]
}
const swapReuslt = swap(["1", 2])
console.log("swapReuslt: ", swapReuslt)


// 泛型约束
interface Lengthwise {
  length: number
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length)
  return arg
}

loggingIdentity("hello") // 输出 5
loggingIdentity([1, 2, 3]) // 输出 3

// 泛型类
class Queue<T> {
  private data: T[] = []
  push(item: T) {
    this.data.push(item)
  }
}

const queue = new Queue<string>()
queue.push("hello")
queue.push("generics")

// 泛型类型别名
type Cart<T> = {list: T[]} | T[]
let c1: Cart<string> = {list:['1']}
let c2: Cart<number> = [1]
console.log(c1,c2)

// 泛型接口
interface keyPair<T,U>{
  key:T,
  value:U
}
let keyPair1 : keyPair<string,string>= {
  key:'name',
  value:'joker'
}
let keyPair2 : keyPair<number,string> ={
  key:0,
  value:'value'
}
console.log(keyPair1,keyPair2)
</script>

<template>
</template>